//Let's start with functions for the WireClua side of things.

WireClua={}
WireClua.BaseDir="../lua/"
WireClua.EnableLua=false

//checks if the player's active weapon is a clua
//Completely stolen from the advanced duplicator
function WireClua.IsCluaTool(tool)
	if (tool) and (tool:GetClass() == "gmod_tool" ) and ( tool:GetTable():GetToolObject() )
	and (tool:GetTable():GetToolObject().Name == "Wire Lua Controller") then
		return true
	else
		return false
	end
end

//This will examine the file to see what's what, and return a table containing the information, or false if it can't find the information
function WireClua.GetFileInfo(contents)
//We look for:
//@ <script name>
//@ <creater>
//@ <contact>
	local size=string.len(contents)
	//This sub will cut a lot of the file off, leaving only the start, which is what we care about.
	contents=string.sub(contents,1,250)
	local name,creator,contact=string.match(contents,"//@([^\n]*)\n//@([^\n]*)\n//@([^\n]*)\n")
	if(name==nil or creator==nil or contact==nil) then
		return false
	end
	return {
		name=name,
		creator=creator,
		contact=contact,
		size=size,
	}
end

if SERVER then
	function WireClua.Make(pl, Pos, Ang, Name, Inputs, Outputs, Lua) //Stuff
		if not pl:CheckLimit("wire_clua") then return false end
		if(Name==nil or Name=="") then
			pl:SendLua("GAMEMODE:AddNotify(\"Wire_clua: No name\",NOTIFY_CLEANUP,5)")
			return false
		end
		WireClua.Ents[pl]=WireClua.Ents[pl] or {}
		if(WireClua.Ents[pl][Name]!=nil) then
			pl:SendLua("GAMEMODE:AddNotify(\"Wire_clua: Non unique name\",NOTIFY_CLEANUP,5)")
			return false
		end
		
		local wire_clua = ents.Create("gmod_wire_clua")
		if not wire_clua:IsValid() then return false end
		
		wire_clua:SetAngles(Ang)
		wire_clua:SetPos(Pos)
		wire_clua:Spawn()
		wire_clua:SetPlayer(pl)
		wire_clua.pl = pl
		
		pl:AddCount("wire_clua", wire_clua)
		
		wire_clua:SetNameC(Name)
		if Inputs then
			wire_clua:SetInputs(Inputs)
		end
		if Outputs then
			wire_clua:SetOutputs(Outputs)
		end
		if Lua then
			wire_clua:SetLua(Lua)
		end
		//Store some info for the entity
		
		return wire_clua
	end
	//Stuff
	duplicator.RegisterEntityClass("gmod_wire_clua", WireClua.Make, "Pos", "Ang", "Name", "Inputs", "Outputs", "Lua", "Vel", "aVel", "frozen")

	CreateConVar('sbox_maxwire_clua', 20)
	WireClua.PendingUploads={}
	WireClua.Files={}
	WireClua.Ents={}
	//This table holds the information needed to update outputs.
	//This function is a concommand that handles any clientside wire updates.
	function WireClua.Update(ply,cmd,args)
		if(WireClua.Ents[ply]==nil) then return end
		if(args[1]==nil or args[2]==nil or args[3]==nil) then return end
		local name,out
		name=args[1]
		out=args[2]
		if(WireClua.Ents[ply][name]==nil) then return end
		if(WireClua.Ents[ply][name]:IsValid()!=true) then return end
		if(WireClua.Ents[ply][name].Outputs==nil) then return end
		out=string.upper(string.sub(out,1,1))..string.lower(string.sub(out,2))
		if(WireClua.Ents[ply][name].Outputs[out]==nil) then return end
		Wire_TriggerOutput(WireClua.Ents[ply][name],out,tonumber(args[3]) or 0)
	end
	concommand.Add("wire_c_update",WireClua.Update)
	
	function WireClua.Copy(ply,cmd,args)
		local tr=util.GetPlayerTrace(ply)
		tr=util.TraceLine(tr)
		if(tr.HitNonWorld) then
			local ent
			ent=tr.Entity
			if(ent:IsValid()) then
				if ent:IsValid() and ent:GetClass() == "gmod_wire_clua" and ent:GetTable().pl == ply then
					local ins=""
					if(ent.Inputs) then
						for name in pairs(ent.Inputs) do
							ins=ins..name.." "
						end
					end
					local outs=""
					if(ent.Outputs) then
						for name in pairs(ent.Outputs) do
							outs=outs..name.." "
						end
					end
					umsg.Start("WireClua.SetInfo",ply)
						umsg.String(string.lower(ent.Name or ""))
						umsg.String(string.lower(ins))
						umsg.String(string.lower(outs))
					umsg.End()
				end
			end
		end
	end
	concommand.Add("wire_c_copy",WireClua.Copy)
	
	function WireClua.SetNameC(ply,name,ent)
		umsg.Start("WireClua.SetNameC",ply)
			umsg.String(name)
			umsg.Entity(ent)
		umsg.End()
	end
	
	if(WireClua.EnableLua) then
		//Request a file from the client
		function WireClua.Load(ply,cmd,args)
			local tool=ply:GetActiveWeapon()
			if(WireClua.IsCluaTool(tool)!=true) then return end
			local uploadid=tls.GetID()
			//Only one upload at a time.
			if(WireClua.PendingUploads[uploadid]!=nil) then return end
			umsg.Start("WireClua.SendFile",ply)
				umsg.String(ply:GetInfo("wire_clua_filename"))
				umsg.Long(uploadid)
			umsg.End()
			WireClua.PendingUploads[uploadid]=ply //Store our player for future use
			tls.Hook("CluaU"..tostring(uploadid),tostring(uploadid),WireClua.HandleUpload)
		end
		concommand.Add("wire_c_load",WireClua.Load)
		
		//If the upload fails then this is called to cancel the upload.
		function WireClua.Failed(ply,cmd,args)
			args[1]=tonumber(args[1])
			if(args[1]) then
				if(tls.ids[args[1]]) then
					tls.Unhook("CluaU"..tostring(args[1]),tostring(args[1]))
					tls.ids[args[1]]=nil
					WireClua.PendingUploads[args[1]]=nil
				end
			end
		end
		concommand.Add("wire_c_failed",WireClua.Failed)

		function WireClua.HandleUpload(str,call,uploadid)
			//Uploadid is our id, it was passed via the call.
			uploadid=tonumber(uploadid)
			if(uploadid==nil) then return end
			//Unhook ourselfs. We rehook whenever it needs doing.
			tls.Unhook("CluaU"..tostring(uploadid),tostring(uploadid))
			//Nab our player etc.
			local ply=WireClua.PendingUploads[uploadid]
			if(ply==nil) then return end
			WireClua.PendingUploads[uploadid]=nil
			//Getinfo will get us our file info. It has to have it to pass this far.
			local info=WireClua.GetFileInfo(str)
			//But still, if it doesn't...
			if(info) then
				//Tell our client that we got it
				umsg.Start("WireClua.RecieveInfo",ply)
					umsg.String(info.name)
					umsg.String(info.creator)
					umsg.String(info.contact)
					umsg.Long(info.size)
				umsg.End()
				//Store our file.
				WireClua.Files[ply]=str
				//Since this is as good a chance as any, check our uploads to see if everybody is still there:
				for ply in pairs(WireClua.Files) do
					if(ply:IsValid()==false) then
						WireClua.Files[ply]=nil
					end
				end
			end
		end
		function WireClua.SetLua(ent,arg)
			ent:SetLua(arg)
		end
	else
		function WireClua.Load(ply,cmd,args)
			umsg.Start("WireClua.SetMessage",ply)
				umsg.String("Embedding is not allowed on this server.")
			umsg.End()
		end
		concommand.Add("wire_c_load",WireClua.Load)
	end
end

if(CLIENT) then
	WireClua.Ins={}
	WireClua.Outs={}
	WireClua.Ents={}
	//This function functions as a safe passage for inputs. Inputs are passed down through this.
	function WireClua.Handle(input,value,self)
		if(WireClua.Ins[self.Name or ""]) then
			WireClua.Ins[self.Name][input]=value
		end
	end
	//This one recieves the status message
	function WireClua.Msg(um)
		local input,value,self
		input=um:ReadString()
		value=um:ReadFloat()
		self=um:ReadEntity()
		WireClua.Handle(input,value,self)
	end
	usermessage.Hook("WireClua.Msg",WireClua.Msg)

	//This one recieves any name changes
	function WireClua.SetNameC(um)
		local name,ent
		name=um:ReadString()
		ent=um:ReadEntity()

		if(WireClua.Ents[name]==nil) then
			WireClua.Ents[name]=ent
			WireClua.Ins[name]={}
			WireClua.Outs[name]={}
		end
		if(ent.Name and ent.Name!=name) then
			WireClua.Ins[name]=table.Copy(WireClua.Ins[ent.Name] or {})
			WireClua.Outs[name]=table.Copy(WireClua.Outs[ent.Name] or {})
			WireClua.Ents[ent.Name]=nil
			WireClua.Ins[ent.Name]=nil
			WireClua.Outs[ent.Name]=nil
		end
		ent.Name=name
		for name,ent in pairs(WireClua.Ents) do
			if(ent:IsValid()==false) then
				WireClua.Ents[name]=nil
				WireClua.Ins[name]=nil
				WireClua.Outs[name]=nil
			end
		end
	end
	usermessage.Hook("WireClua.SetNameC",WireClua.SetNameC)
	
	function WireClua.Send(name,output,value)
		LocalPlayer():ConCommand("wire_c_update "..name.." "..output.." "..value)
	end
	
	//if(WireClua.EnableLua) then
		//This can be either trigger by a usermessage, or manually.
		function WireClua.SetMessage(um)
			local message
			if(type(um)=="string") then
				message=um
			else
				message=um:ReadString()
			end
			if(message=="") then
				WireClua.Message=nil
			else
				WireClua.Message=message
			end
			WireClua.RebuildPanel()
		end
		usermessage.Hook("WireClua.SetMessage",WireClua.SetMessage)
		
		function WireClua.ReloadLua(um)
			local ent=um:ReadEntity()
			ent:ReloadLua() //Now it's clientside.
		end
		usermessage.Hook("WireClua.ReloadLua",WireClua.ReloadLua)
		
		function WireClua.SetInfo(um)
			local name=um:ReadString()
			if(name!="") then
				RunConsoleCommand("wire_clua_name",name)
			end
			local ins=um:ReadString()
			if(ins!="") then
				RunConsoleCommand("wire_clua_inputs",ins)
			end
			local outs=um:ReadString()
			if(outs!="") then
				RunConsoleCommand("wire_clua_outputs",outs)
			end
		end
		usermessage.Hook("WireClua.SetInfo",WireClua.SetInfo)
		
		//Uploads the file, if it is cool.
		function WireClua.SendFile(um)
			local filename,requestid
			filename=um:ReadString()
			requestid=um:ReadLong()
			//One at a time.
			if(WireClua.Uploading==true) then
				LocalPlayer():ConCommand("wire_c_failed "..tostring(requestid))
				return
			end
			//Bleh, clean.
			//No escaped or absolute directories
			if(string.find(filename,"%.%.")==nil) then
				//Prepend the location
				filename=WireClua.BaseDir..filename
				if(file.Exists(filename)) then
					//Upload our file.
					local lua=file.Read(filename)
					local lualength=string.len(lua)
					//Check to see if the string is too big.
					if(lualength>tls.settings.maxstringsize) then
						//Send them the message. The math converts it into xx.xKb
						WireClua.SetMessage("Filesize is "..
						tostring(math.floor(lualength/100)/10)..
						"Kb, which is larger than the maximum of "..
						tostring(math.floor(tls.settings.maxstringsize/100)/10).."Kb")
						//Inform the server that there is no upload
						LocalPlayer():ConCommand("wire_c_failed "..tostring(requestid))
						return
					end
					//We must have info
					local info=WireClua.GetFileInfo(lua)
					if(info==false) then
						LocalPlayer():ConCommand("wire_c_failed "..tostring(requestid))
						WireClua.SetMessage(
[[File info not found. You must include:
//@ <script name>
//@ <creater>
//@ <contact>
at the start of your file.]]
						)
						return
					end
					WireClua.Uploading=true
					local id=tls.InitUL(lua,"CluaU"..tostring(requestid),WireClua.UploadStatus)
					//This updates the time shown on the panel.
					timer.Create("WireClua.UpdateTime"..tostring(id),.1,0,WireClua.UpdateTime,id)
					return
				end
				LocalPlayer():ConCommand("wire_c_failed "..tostring(requestid))
				WireClua.SetMessage("Upload failed, file does not exist.")
				return
			end
			LocalPlayer():ConCommand("wire_c_failed "..tostring(requestid))
			WireClua.SetMessage("Upload failed, invalid characters in filename.")
		end
		usermessage.Hook("WireClua.SendFile",WireClua.SendFile)
		
		function WireClua.UpdateTime(id)
			//If the upload status table exists...
			if(tls.uploads[id]) then
				local timeremaining=(tls.uploads[id].remaining/tls.settings.maxchunksize)*tls.settings.chunkdelay
				timeremaining=math.floor(timeremaining*100)/100
				WireClua.SetMessage("Uploading, estimated time remaining: "..
				tostring(timeremaining)..
				" seconds.")
			else
				//If the table no longer exists, it probably finished.
				timer.Destroy("WireClua.UpdateTime"..tostring(id))
			end
		end
		
		function WireClua.UploadStatus(suc)
			//Our status indicator message
			if(suc) then
				WireClua.SetMessage("Upload finished.")
			else
				WireClua.SetMessage("Upload error.")
			end
			WireClua.Uploading=nil
		end
		
		//This recieves the information about the uploaded file
		function WireClua.RecieveInfo(um)
			local name,creator,contact,size
			name=um:ReadString()
			creator=um:ReadString()
			contact=um:ReadString()
			size=um:ReadLong()
			if(name=="") then
				WireClua.FileInfo=nil
			else
				WireClua.FileInfo="Name: "..name..
				"\nCreator: "..creator..
				"\nContact: "..contact..
				"\nSize: "..tostring(math.floor(size/100)/10).."Kb"
			end
			WireClua.RebuildPanel()
		end
		usermessage.Hook("WireClua.RecieveInfo",WireClua.RecieveInfo)
		
		WireClua.PendingDownload={}
		//This recieves the information about the uploaded file
		function WireClua.RecieveDownloadInfo(um)
			local name,creator,contact,size
			ent=um:ReadEntity()
			id=um:ReadLong()
			WireClua.PendingDownload.ent=ent
			WireClua.PendingDownload.id=id
		end
		usermessage.Hook("WireClua.RecieveDownloadInfo",WireClua.RecieveDownloadInfo)
		

		
		function WireClua.SetLua(lua)
			local ent=WireClua.PendingDownload.ent
			local ply=LocalPlayer()
			if ent:IsValid() and ent:GetClass() == "gmod_wire_clua" and ent:GetTable().pl == ply then
				ent:SetLua(lua) //Boom. Set lua is now clientside.
			end
		end
		//In order to remove the dot, I do this. The string transfer thing can't handle tables.
		WireClua_SetLua=WireClua.SetLua
		
		//This is ugly, but I don't know how to make it good.
		function WireClua.ConfirmLua(ent,lua)
			if(lua=="") then
				WireClua.Confirm.Ent.Confirmed=true
				WireClua.Confirm.Ent:ReloadLua()
			end
			if(ent:IsValid()==false) then return end
			if(ent:GetClass()!="gmod_wire_clua") then return end
			if(!WireClua.Confirm) then
				WireClua.Confirm={}
				WireClua.Confirm.Frame=vgui.Create("DFrame")
				WireClua.Confirm.Frame:SetTitle("Confirm embed lua")
				WireClua.Confirm.Frame:SetDeleteOnClose(false)
				WireClua.Confirm.Frame:SetDraggable(false)
				WireClua.Confirm.Frame:SetSize(700,500)
				WireClua.Confirm.Frame:Center()
				WireClua.Confirm.Frame:ShowCloseButton(false)
				
				WireClua.Confirm.Clabel=vgui.Create("Label",WireClua.Confirm.Frame,"Clabel")
				WireClua.Confirm.Clabel:SetPos(6,25)
				WireClua.Confirm.Clabel:SetSize(400,25)
				WireClua.Confirm.Clabel:SetText("-WARNING-WARNING- Confirm that you wish to embed and run this code:")
				
				WireClua.Confirm.Cbutton=vgui.Create("DButton",WireClua.Confirm.Frame,"Cbutton")
				WireClua.Confirm.Cbutton:SetPos(594,25)
				WireClua.Confirm.Cbutton:SetSize(100,25)
				WireClua.Confirm.Cbutton:SetText("Confirm")
				function WireClua.Confirm.Cbutton:DoClick()
					WireClua.Confirm.Ent.Confirmed=true
					WireClua.Confirm.Ent:ReloadLua()
					WireClua.Confirm.Ent=nil
					WireClua.Confirm.Lua:SetHTML("")
					WireClua.Confirm.Frame:Close()
				end
				
				WireClua.Confirm.Dbutton=vgui.Create("DButton",WireClua.Confirm.Frame,"Dbutton")
				WireClua.Confirm.Dbutton:SetPos(494,25)
				WireClua.Confirm.Dbutton:SetSize(100,25)
				WireClua.Confirm.Dbutton:SetText("DENY!")
				function WireClua.Confirm.Dbutton:DoClick()

					WireClua.Confirm.Lua:SetHTML("")
					WireClua.Confirm.Frame:Close()
				end
				
				WireClua.Confirm.Lua=vgui.Create("HTML",WireClua.Confirm.Frame,"Lua")
				WireClua.Confirm.Lua:SetPos(6,52)
				WireClua.Confirm.Lua:SetSize(668,422)
				WireClua.Confirm.Lua:SetHTML("")
				function WireClua.Confirm.Lua:OpeningURL(url,target)
					local command=url:gsub("lua://ShowHelp/","")
					for name,info in pairs(WireClua.Dict) do
						if(name==command) then
							//Do command thing.
						end
					end
				end

			end
			WireClua.Confirm.Ent=ent
			WireClua.Confirm.Lua:SetHTML(WireClua.Scan(lua))
			
			WireClua.Confirm.Frame:MakePopup()
			WireClua.Confirm.Frame:SetMouseInputEnabled(true)
			WireClua.Confirm.Frame:SetVisible(true)
		end
		//Wrapper to add dictionary entries
		local function adddict(name,pattern,warn,info)
			WireClua.Dict[name]={info,pattern,warn}
		end
		//Our dictionary.
		WireClua.Dict={}
		//Warn:
		//1 Caution
		//2 Danger
		//3 Shouldn't run
		//		Name					Pattern				Warn		Info
		adddict("Rcon"				,"rcon"				,2,"Short for remote console, could steal passwords, or allow remote control of your game.")
		adddict("Rcon password"		,"rcon_password"	,3,"This is the password to control the server, possible attempt to steal control.")
		adddict("Hook"				,"hook\."			,1,"Hook could be dangerous, though it is commonly used for good.")
		adddict("Concommand"		,"concommand\."		,1,"Concommand could hijack functions, though it is commonly used for good.")
		adddict("File"				,"file\."			,2,"File access is dangerous, though it is commonly used for good.")
		adddict("SQL"				,"sql\."			,1,"SQL can erase things like ratings, though it is commonly used for good.")
		adddict("HTTP"				,"http"				,2,"HTTP can upload things to a server, such as passwords. Check the function context.")
		adddict("Console Command"	,"RunConsoleCommand",1,"Most bad commands are already blocked, but it can still cause harm.")
		adddict("Clipboard"			,"SetClipboardText"	,1,"This could erase your clipboard text. Possibly quite annoying.")
		
		//This scans the lua for bad things, and returns html of what to display
		function WireClua.Scan(lua)
			//Similar to code.garrysmod.com
			//Actually, more like ripped off from
			local javascript=""
			for name,info in pairs(WireClua.Dict) do
				javascript=javascript.."function showerror"..string.gsub(name," ","_").."() { alert(\""..name..": "..info[1].."\"); }\n"
			end
			local output=
[[<html>
<head>
<title>Run code?</title>
<style>
<!--
BODY {background-color: #aaa; font-family: Verdana; font-size: 12px;}
SPAN {height: 15px; padding-left:31px; width: 100%;}
.lua1{background-color: #efefef;}
.lua2{background-color: #eaeaea;}
.error1{background-color: #ccffcc;}
.error2{background-color: #ffffcc;}
.error3{background-color: #ffcccc;}
PRE { background-color: #efefef; border: 1px solid #444;}
.ln {color: blue; height: 15px; padding-left:0px;}
.lndiv {text-align: right; border-right: 1px solid #ccc; float: left; width: 30px; padding-right: 2px; position: absolute}
-->
</style>
<script>
<!--
]]..javascript..[[
-->
</script>
</head>
<body>
]]
			local code="<pre><div class=\"lndiv\">"
			//Remove tabs and spaces.
			lua=string.gsub(lua,"	","&nbsp;&nbsp;&nbsp;&nbsp;")
			lua=string.gsub(lua," ","&nbsp;")
			local lines=string.Explode("\n",lua)
			local alt=false
			local class
			local onclick
			local enum
			//Add line numbers in a seperate div
			local i=1
			while(i<#lines+1) do
				code=code.."<span class=\"ln\">"..tostring(i).."</span>"
				i=i+1
			end
			code=code.."</div>"
			//Scan every line for bad things
			for linenum,line in ipairs(lines) do
				//This functions to alternate the line colors
				alt=!alt
				if(alt) then class="lua1" else class="lua2" end
				//Scan for our predefined bad things
				onclick=""
				enum=0
				for name,info in pairs(WireClua.Dict) do
					//If it finds one
					if(string.match(string.lower(line),info[2])!=nil) then
						//Let's catch the worst error
						if(info[3]>enum) then
							enum=info[3]
							//Determine the class for the line of code
							class="error"..tostring(info[3])
							//Determine the javascript of the error to show
							onclick=" onclick=\"showerror"..string.gsub(name," ","_").."()\""
						end
					end
				end
				code=code.."<span class=\""..class.."\""..onclick..">"..line.."</span>\n"
			end
			code=string.sub(code,1,-2)
			code=code.."</pre>"
			
			output=output.."</div>"..code.."</body></html>"
			return output
		end
	//end
	
	function WireClua.RebuildPanel(panel)
		if (!panel) then
			panel=GetControlPanel("wire_clua")
			if(!panel) then return end
		end
		panel:ClearControls()
		
		panel:AddControl("Header", { Text = "#Tool_wire_clua_name", Description = "#Tool_wire_clua_desc" })
		
		panel:AddControl("TextBox", {
			Label = "#WireClua_Name",
			Command = "wire_clua_name"
		})
		
		panel:AddControl("TextBox", {
			Label = "#WireClua_Inputs",
			Command = "wire_clua_inputs"
		})
		
		panel:AddControl("TextBox", {
			Label = "#WireClua_Outputs",
			Command = "wire_clua_outputs"
		})
		
		panel:AddControl("Button", {
			Label = "#WireClua_Copy",
			Command = "wire_c_copy"
		})
		
		panel:AddControl("TextBox", {
			Label = "#WireClua_Filename",
			Command = "wire_clua_filename"
		})
		
		panel:AddControl( "Label", { Text = "Files reside in:\nlua/<filename>" })
		
		panel:AddControl("Button", {
			Label = "#WireClua_Load",
			Command = "wire_c_load"
		})
		
		if(WireClua.Message) then
			panel:AddControl( "Label", { Text = WireClua.Message })
		end
		
		if(WireClua.FileInfo) then
			panel:AddControl( "Label", { Text = WireClua.FileInfo })
		end
		
		panel:AddControl( "Label", { Text = "See http://bottlabs.org/Wire_clua for documentation." })
	end
end

//Actual tool gun stuff.
TOOL.Category = "Wire - I/O"
TOOL.Name = "Wire Lua Controller"
TOOL.Command = nil -- What is this for?
TOOL.ConfigName = ""

if CLIENT then
	language.Add("Tool_wire_clua_name", "Lua Controller")
	language.Add("Tool_wire_clua_desc", "Spawn a Wire Clientside Lua Controller.")
	language.Add("Tool_wire_clua_0", "Primary: Create/update Lua Controller.")
	language.Add("sboxlimit_wire_clua", "You've hit your Lua Controller limit!")
	language.Add("Undone_Wire Clua", "Undone Lua Controller")
	language.Add("WireClua_Filename", "Filename:")
	language.Add("WireClua_Load", "Load")
	language.Add("WireClua_Name", "Name:")
	language.Add("WireClua_Inputs", "Inputs:")
	language.Add("WireClua_Outputs", "Outputs:")
	language.Add("WireClua_Copy", "Copy from current")
end



//Tool config:
TOOL.Model = "models/cheeze/wires/cpu.mdl"
TOOL.ClientConVar["name"] = ""
TOOL.ClientConVar["filename"] = ""
TOOL.ClientConVar["filesize"] = ""
TOOL.ClientConVar["inputs"] = ""
TOOL.ClientConVar["outputs"] = ""

cleanup.Register("wire_clua")

function TOOL:LeftClick(trace)
	if not trace.HitPos then return false end
	if trace.Entity:IsPlayer() then return false end
	if CLIENT then return true end

	local ply = self:GetOwner()
	
	if trace.Entity:IsValid() and trace.Entity:GetClass() == "gmod_wire_clua" and trace.Entity:GetTable().pl == ply and self:GetClientInfo("name")!="" then
		trace.Entity:SetNameC(self:GetClientInfo("name"))
		trace.Entity:SetInputs(self:GetClientInfo("inputs"))
		trace.Entity:SetOutputs(self:GetClientInfo("outputs"))
		//Update entity
		return true
	end

	if not self:GetSWEP():CheckLimit("wire_clua") then return false end

	local Ang = trace.HitNormal:Angle()
	Ang.pitch = Ang.pitch + 90
	//WireClua.Make(pl, Pos, Ang, Name, Inputs, Outputs, Lua, Embedded, ExternalFilename)
	local wire_clua = WireClua.Make(ply, trace.HitPos, Ang, self:GetClientInfo("name"), self:GetClientInfo("inputs"), self:GetClientInfo("outputs")) //Stuff
	if(wire_clua==false) then
		return false
	end
	wire_clua:SetPos(trace.HitPos - trace.HitNormal * wire_clua:OBBMins().z)
	
	
	local const = WireLib.Weld(wire_clua, trace.Entity, trace.PhysicsBone, true)

	undo.Create("Wire Clua")
		undo.AddEntity(wire_clua)
		undo.AddEntity(const)
		undo.SetPlayer(ply)
	undo.Finish()

	ply:AddCleanup("wire_clua", wire_clua)
	

	
	return true
end

function TOOL:RightClick(trace)
	local ply = self:GetOwner()
	if not trace.HitPos then return false end
	if trace.Entity:IsPlayer() then return false end
	if CLIENT then return true end
	local ent=trace.Entity
	if ent:IsValid() and ent:GetClass() == "gmod_wire_clua" and ent:GetTable().pl == ply then
		if(ent.Lua!=nil and ent.Lua!="") then
			ent:SetLua("")
			return true
		else
			if(string.len(WireClua.Files[ply] or "")>0) then
				ent:SetLua(WireClua.Files[ply])
				return true
			end
		end
		//Update entity
		return false
	end
	return false
end

function TOOL:Reload(trace)
	if not trace.HitPos then return false end
	if trace.Entity:IsPlayer() then return false end
	if CLIENT then return true end
	local ply = self:GetOwner()
	local ent=trace.Entity
	if ent:IsValid() and ent:GetClass() == "gmod_wire_clua" and ent:GetTable().pl == ply then
		ent:ReloadLua()
		//Update entity
		return true
	end
	return false
end

function TOOL:UpdateGhostWirePod(ent, player)
	if  not ent or not ent:IsValid() then return end

	local tr = utilx.GetPlayerTrace(player, player:GetCursorAimVector())
	local trace = util.TraceLine(tr)

	if not trace.Hit or trace.Entity:IsPlayer() or trace.Entity:GetClass() == "gmod_wire_clua" then
		ent:SetNoDraw(true)
		return
	end

	local Ang = trace.HitNormal:Angle()
	Ang.pitch = Ang.pitch + 90

	ent:SetPos(trace.HitPos - trace.HitNormal * ent:OBBMins().z)
	ent:SetAngles(Ang)

	ent:SetNoDraw(false)
end

function TOOL:Think()
	if not self.GhostEntity or not self.GhostEntity:IsValid() or self.GhostEntity:GetModel() ~= self.Model then
		self:MakeGhostEntity(self.Model, Vector(0,0,0), Angle(0,0,0))
	end

	self:UpdateGhostWirePod(self.GhostEntity, self:GetOwner())
end

function TOOL.BuildCPanel(panel)
	WireClua.RebuildPanel(panel)
end